home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 46 / Amiga Format CD46 (1999-10-20)(Future Publishing)(GB)[!][issue 1999-12].iso / -serious- / misc / nroff / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-06  |  19.5 KB  |  1,005 lines

  1. #include "config.h"
  2.  
  3. /*
  4.  *    main.c - main for nroff word processor
  5.  *
  6.  *    similar to Unix(tm) nroff or RSX-11M RNO. adaptation of text processor
  7.  *    given in "Software Tools", Kernighan and Plauger.
  8.  *
  9.  *    adapted for atariST/TOS by Bill Rosenkranz 11/89
  10.  *    net:    rosenkra@hall.cray.com
  11.  *    CIS:    71460,17
  12.  *    GENIE:    W.ROSENKRANZ
  13.  *
  14.  *    original author:
  15.  *
  16.  *    Stephen L. Browning
  17.  *    5723 North Parker Avenue
  18.  *    Indianapolis, Indiana 46220
  19.  *
  20.  *    history:
  21.  *
  22.  *    - Originally written in BDS C;
  23.  *    - Adapted for standard C by W. N. Paul
  24.  *    - Heavily hacked up to conform to "real" nroff by Bill Rosenkranz
  25.  */
  26.  
  27. #define NRO_MAIN            /* to define globals in nro.h */
  28.  
  29. #include <stdio.h>
  30. #ifdef GEMDOS
  31. #include <sys\types.h>
  32. #include <sys\time.h>
  33. #else
  34. #include <sys/types.h>
  35. #include <sys/time.h>
  36. #endif
  37. #include "nroff.h"
  38.  
  39.  
  40. main (argc, argv)
  41. int     argc;
  42. char   *argv[];
  43. {
  44.     register int    i;
  45.     int        swflg;
  46.     int        ifp = 0;
  47.     char           *ptmp;
  48. #ifndef GEMDOS
  49. # ifndef  _AMIGA
  50.     char           *pterm;
  51.     char        capability[100];
  52.     char           *pcap;
  53.     char           *ps;
  54. # endif
  55. #endif
  56.  
  57.  
  58.  
  59.     /*
  60.      *   set up initial flags and file descriptors
  61.      */
  62.     swflg       = FALSE;
  63.     ignoring    = FALSE;
  64.     hold_screen = FALSE;
  65.     debugging   = FALSE;
  66.     stepping    = FALSE;
  67.     mc_ing      = FALSE;
  68.     out_stream  = stdout;
  69.     err_stream  = stderr;
  70.     dbg_stream  = stderr;
  71.  
  72.  
  73.     /*
  74.      *   this is for tmp files, if ever needed. it SHOULD start
  75.      *   out without the trailing slash. if not in env, use default
  76.      */
  77.     if (ptmp = getenv ("TMPDIR"))
  78.         strcpy (tmpdir, ptmp);
  79.     else
  80.         strcpy (tmpdir, ".");
  81.  
  82.  
  83.     /*
  84.      *   handle terminal for \fB, \fI
  85.      */
  86. #ifdef GEMDOS
  87.     strcpy (s_standout, "\33p");        /* atari/TOS is easy... */
  88.     strcpy (e_standout, "\33q");
  89.     strcpy (s_bold, "\33p");        /* atari/TOS is easy... */
  90.     strcpy (e_bold, "\33q");
  91.     strcpy (s_italic, "\33p");
  92.     strcpy (e_italic, "\33q");
  93. #else
  94. # ifdef _AMIGA
  95.     strcpy (s_standout, "\2337m");
  96.     strcpy (e_standout, "\233m");
  97.     strcpy (s_bold, "\2331m");
  98.     strcpy (e_bold, "\23322m");
  99.     strcpy (s_italic, "\2333m");
  100.     strcpy (e_italic, "\23323m");
  101. # else
  102.     s_standout[0] = '\0';
  103.     e_standout[0] = '\0';
  104.     s_bold[0]     = '\0';
  105.     e_bold[0]     = '\0';
  106.     s_italic[0]   = '\0';
  107.     e_italic[0]   = '\0';
  108.     if (pterm = getenv ("TERM"))        /* it must exist first... */
  109.     {
  110.         /*
  111.          *   we currently use standout mode for all weirdness
  112.          *   lile BOLD, italic, etc.
  113.          */
  114.         pcap = capability;
  115.         if (ps = "\\E[7m") /*sorry had to hard code these for damn linux*/
  116.         {
  117.             /*
  118.              *   sun has padding in here. this is NOT portable.
  119.              *   better to use tputs() to strip it...
  120.              */
  121.             while (*ps && *ps != 0x1b)    ps++;
  122.             strcpy (s_standout, ps);
  123.             strcpy (s_bold, ps);
  124.             strcpy (s_italic, ps);
  125.         }
  126.         if (ps = "\\E[m")
  127.         {
  128.             while (*ps && *ps != 0x1b)    ps++;
  129.             strcpy (e_standout, ps);
  130.             strcpy (e_bold, ps);
  131.             strcpy (e_italic, ps);
  132.         }
  133.     }
  134. # endif
  135. #endif
  136.  
  137.  
  138.  
  139.     /*
  140.      *   initialize structures (defaults)
  141.      */
  142.     init ();
  143.  
  144.  
  145.     /*
  146.      *   parse cmdline flags
  147.      */
  148.     for (i = 1; i < argc; ++i)
  149.     {
  150.         if (*argv[i] == '-' || *argv[i] == '+')
  151.         {
  152.             if (pswitch (argv[i], &swflg) == ERR)
  153.                 err_exit (-1);
  154.         }
  155.     }
  156.  
  157.  
  158.     /*
  159.      *   loop on files
  160.      */
  161.     for (i = 1; i < argc; ++i)
  162.     {
  163.         if (*argv[i] != '-' && *argv[i] != '+')
  164.         {
  165.             /*
  166.              *   open this file...
  167.              */
  168.             if ((sofile[0] = fopen (argv[i], "r")) == NULL_FPTR)
  169.             {
  170.                 fprintf (err_stream,
  171.                     "***%s: unable to open file %s\n",
  172.                     myname, argv[i]);
  173.                 err_exit (-1);
  174.             }
  175.             else
  176.             {
  177.                 /*
  178.                  *   do it for this file...
  179.                  */
  180.                 ifp = 1;
  181.                 profile ();
  182.                 fclose (sofile[0]);
  183.             }
  184.         }
  185.         else if (*argv[i] == '-' && *(argv[i]+1) == 0)
  186.         {
  187.             /*
  188.              *   - means read stdin (anywhere in file list)
  189.              */
  190.             sofile[0] = stdin;
  191.             ifp = 1;
  192.             profile ();
  193.         }
  194.  
  195.     }
  196.  
  197.  
  198.     /*
  199.      *   if no files, usage (should really use stdin...)
  200.      */
  201.     if ((ifp == 0 && swflg == FALSE) || argc <= 1)
  202.     {
  203.         usage ();
  204.  
  205.         err_exit (-1);
  206.     }
  207.  
  208.  
  209.     /*
  210.      *   normal exit. this will fflush/fclose streams...
  211.      */
  212.     err_exit (0);
  213. }
  214.  
  215.  
  216.  
  217.  
  218. /*------------------------------*/
  219. /*    usage            */
  220. /*------------------------------*/
  221. usage ()
  222. {
  223.     /*
  224.      *   note: -l may not work correctly
  225.      */
  226.     fprintf (stderr, "Usage:   %s [options] file [...]\n", myname);
  227.     fprintf (stderr, "Options: -a        no font changes\n");
  228.     fprintf (stderr, "         -b        backspace\n");
  229.     fprintf (stderr, "         -d        debug mode (file: nroff.dbg)\n");
  230. #ifdef GEMDOS
  231.     fprintf (stderr, "         -h        hold screen before desktop\n");
  232. #endif
  233. /*!!!    fprintf (stderr, "         -l        output to printer\n");*/
  234.     fprintf (stderr, "         -m<name>  macro file (e.g. -man)\n");
  235.     fprintf (stderr, "         -o<file>  error log file (stderr is default)\n");
  236.     fprintf (stderr, "         -po<n>    page offset\n");
  237.     fprintf (stderr, "         -pn<n>    initial page number\n");
  238.     fprintf (stderr, "         -pl<n>    page length\n");
  239.     fprintf (stderr, "         -s        step through pages\n");
  240.     fprintf (stderr, "         -v        print version only\n");
  241.     fprintf (stderr, "         +<n>      first page to do\n");
  242.     fprintf (stderr, "         -<n>      last page to do\n");
  243.     fprintf (stderr, "         -         use stdin (in file list)\n");
  244. }
  245.  
  246.  
  247.  
  248.  
  249. /*------------------------------*/
  250. /*    init            */
  251. /*------------------------------*/
  252. init ()
  253. {
  254.  
  255. /*
  256.  *    initialize parameters for nro word processor
  257.  */
  258.  
  259.     extern long    time ();
  260.  
  261. #ifdef MINIX
  262.     register int    i;
  263. #else
  264.     register long    i;
  265. #endif
  266.     time_t        tval;
  267.     char           *ctim;
  268.  
  269.     /*
  270.      *   misc global flags, etc...
  271.      */
  272.     mc_space   = 2;
  273.     mc_char    = '|';
  274.     tval       = time (0L);
  275.     ctim       = ctime (&tval);
  276.  
  277.     /*
  278.      *   basic document controls...
  279.      */
  280.     dc.fill    = YES;
  281.     dc.dofnt   = YES;
  282.     dc.lsval   = 1;
  283.     dc.inval   = 0;
  284.     dc.rmval   = PAGEWIDTH - 1;
  285.     dc.llval   = PAGEWIDTH - 1;
  286.     dc.ltval   = PAGEWIDTH - 1;
  287.     dc.tival   = 0;
  288.     dc.ceval   = 0;
  289.     dc.ulval   = 0;
  290.     dc.cuval   = 0;
  291.     dc.juval   = YES;
  292.     dc.adjval  = ADJ_BOTH;
  293.     dc.boval   = 0;
  294.     dc.bsflg   = FALSE;
  295.     dc.prflg   = TRUE;
  296.     dc.sprdir  = 0;
  297.     dc.flevel  = 0;
  298.     dc.lastfnt = 1;
  299.     dc.thisfnt = 1;
  300.     dc.escon   = YES;
  301.     dc.pgchr   = '%';
  302.     dc.cmdchr  = '.';
  303.     dc.escchr  = '\\';
  304.     dc.nobrchr  = '\'';
  305.     for (i = 0; i < 26; ++i)
  306.         dc.nr[i] = 0;
  307.     for (i = 0; i < 26; ++i)
  308.         dc.nrauto[i] = 1;
  309.     for (i = 0; i < 26; ++i)
  310.         dc.nrfmt[i] = '1';
  311.  
  312.  
  313.     /*
  314.      *   initialize internal regs. first zero out...
  315.      */
  316.     for (i = 0; i < MAXREGS; i++)
  317.     {
  318.         rg[i].rname[0] = EOS;
  319.         rg[i].rname[1] = EOS;
  320.         rg[i].rname[2] = EOS;
  321.         rg[i].rname[3] = EOS;
  322.         rg[i].rauto = 1;
  323.         rg[i].rval  = 0;
  324.         rg[i].rflag = RF_READ;
  325.         rg[i].rfmt  = '1';
  326.     }
  327.  
  328.  
  329.     /*
  330.      *   predefined regs. these are read/write:
  331.      */
  332.     i = 0;
  333.  
  334.     strcpy (rg[i].rname, "%");        /* current page */
  335.     rg[i].rauto = 1;
  336.     rg[i].rval  = 0;
  337.     rg[i].rflag = RF_READ | RF_WRITE;
  338.     rg[i].rfmt  = '1';
  339.     i++;
  340.     
  341.     strcpy (rg[i].rname, "ct");        /* character type */
  342.     rg[i].rauto = 1;
  343.     rg[i].rval  = 0;
  344.     rg[i].rflag = RF_READ | RF_WRITE;
  345.     rg[i].rfmt  = '1';
  346.     i++;
  347.     
  348.     strcpy (rg[i].rname, "dl");        /* width of last complete di */
  349.     rg[i].rauto = 1;
  350.     rg[i].rval  = 0;
  351.     rg[i].rflag = RF_READ | RF_WRITE;
  352.     rg[i].rfmt  = '1';
  353.     i++;
  354.     
  355.     strcpy (rg[i].rname, "dn");        /* height of last complete di */
  356.     rg[i].rauto = 1;
  357.     rg[i].rval  = 0;
  358.     rg[i].rflag = RF_READ | RF_WRITE;
  359.     rg[i].rfmt  = '1';
  360.     i++;
  361.     
  362.     strcpy (rg[i].rname, "dw");        /* day of week (1-7) */
  363.     rg[i].rval  = 0;
  364.     if      (!strncmp (&ctim[0], "Sun", 3))
  365.         rg[i].rval  = 1;
  366.     else if (!strncmp (&ctim[0], "Mon", 3))
  367.         rg[i].rval  = 2;
  368.     else if (!strncmp (&ctim[0], "Tue", 3))
  369.         rg[i].rval  = 3;
  370.     else if (!strncmp (&ctim[0], "Wed", 3))
  371.         rg[i].rval  = 4;
  372.     else if (!strncmp (&ctim[0], "Thu", 3))
  373.         rg[i].rval  = 5;
  374.     else if (!strncmp (&ctim[0], "Fri", 3))
  375.         rg[i].rval  = 6;
  376.     else if (!strncmp (&ctim[0], "Sat", 3))
  377.         rg[i].rval  = 7;
  378.     rg[i].rauto = 1;
  379.     rg[i].rflag = RF_READ | RF_WRITE;
  380.     rg[i].rfmt  = '1';
  381.     i++;
  382.     
  383.     strcpy (rg[i].rname, "dy");        /* day of month (1-31) */
  384.     rg[i].rauto = 1;
  385.     rg[i].rval  = atoi (&ctim[8]);
  386.     rg[i].rflag = RF_READ | RF_WRITE;
  387.     rg[i].rfmt  = '1';
  388.     i++;
  389.     
  390.     strcpy (rg[i].rname, "hp");        /* current h pos on input */
  391.     rg[i].rauto = 1;
  392.     rg[i].rval  = 0;
  393.     rg[i].rflag = RF_READ | RF_WRITE;
  394.     rg[i].rfmt  = '1';
  395.     i++;
  396.     
  397.     strcpy (rg[i].rname, "ln");        /* output line num */
  398.     rg[i].rauto = 1;
  399.     rg[i].rval  = 0;
  400.     rg[i].rflag = RF_READ | RF_WRITE;
  401.     rg[i].rfmt  = '1';
  402.     i++;
  403.     
  404.     strcpy (rg[i].rname, "mo");        /* current month (1-12) */
  405.     rg[i].rval  = 0;
  406.     if      (!strncmp (&ctim[4], "Jan", 3))
  407.         rg[i].rval  = 1;
  408.     else if (!strncmp (&ctim[4], "Feb", 3))
  409.         rg[i].rval  = 2;
  410.     else if (!strncmp (&ctim[4], "Mar", 3))
  411.         rg[i].rval  = 3;
  412.     else if (!strncmp (&ctim[4], "Apr", 3))
  413.         rg[i].rval  = 4;
  414.     else if (!strncmp (&ctim[4], "May", 3))
  415.         rg[i].rval  = 5;
  416.     else if (!strncmp (&ctim[4], "Jun", 3))
  417.         rg[i].rval  = 6;
  418.     else if (!strncmp (&ctim[4], "Jul", 3))
  419.         rg[i].rval  = 7;
  420.     else if (!strncmp (&ctim[4], "Aug", 3))
  421.         rg[i].rval  = 8;
  422.     else if (!strncmp (&ctim[4], "Sep", 3))
  423.         rg[i].rval  = 9;
  424.     else if (!strncmp (&ctim[4], "Oct", 3))
  425.         rg[i].rval  = 10;
  426.     else if (!strncmp (&ctim[4], "Nov", 3))
  427.         rg[i].rval  = 11;
  428.     else if (!strncmp (&ctim[4], "Dec", 3))
  429.         rg[i].rval  = 12;
  430.     rg[i].rauto = 1;
  431.     rg[i].rflag = RF_READ | RF_WRITE;
  432.     rg[i].rfmt  = '1';
  433.     i++;
  434.     
  435.     strcpy (rg[i].rname, "nl");        /* v pos of last base-line */
  436.     rg[i].rauto = 1;
  437.     rg[i].rval  = 0;
  438.     rg[i].rflag = RF_READ | RF_WRITE;
  439.     rg[i].rfmt  = '1';
  440.     i++;
  441.     
  442.     strcpy (rg[i].rname, "sb");        /* depth of str below base */
  443.     rg[i].rauto = 1;
  444.     rg[i].rval  = 0;
  445.     rg[i].rflag = RF_READ | RF_WRITE;
  446.     rg[i].rfmt  = '1';
  447.     i++;
  448.     
  449.     strcpy (rg[i].rname, "st");        /* height of str above base */
  450.     rg[i].rauto = 1;
  451.     rg[i].rval  = 0;
  452.     rg[i].rflag = RF_READ | RF_WRITE;
  453.     rg[i].rfmt  = '1';
  454.     i++;
  455.     
  456.     strcpy (rg[i].rname, "yr");        /* last 2 dig of current year*/
  457.     rg[i].rauto = 1;
  458.     rg[i].rval  = atoi (&ctim[22]);
  459.     rg[i].rflag = RF_READ | RF_WRITE;
  460.     rg[i].rfmt  = '1';
  461.     i++;
  462.     
  463.     strcpy (rg[i].rname, "hh");        /* current hour (0-23) */
  464.     rg[i].rauto = 1;
  465.     rg[i].rval  = atoi (&ctim[11]);
  466.     rg[i].rflag = RF_READ | RF_WRITE;
  467.     rg[i].rfmt  = 2 | 0x80;
  468.     i++;
  469.     
  470.     strcpy (rg[i].rname, "mm");        /* current minute (0-59) */
  471.     rg[i].rauto = 1;
  472.     rg[i].rval  = atoi (&ctim[14]);
  473.     rg[i].rflag = RF_READ | RF_WRITE;
  474.     rg[i].rfmt  = 2 | 0x80;
  475.     i++;
  476.     
  477.     strcpy (rg[i].rname, "ss");        /* current second (0-59) */
  478.     rg[i].rauto = 1;
  479.     rg[i].rval  = atoi (&ctim[17]);
  480.     rg[i].rflag = RF_READ | RF_WRITE;
  481.     rg[i].rfmt  = 2 | 0x80;
  482.     i++;
  483.     
  484.  
  485.     /*
  486.      *   these are read only (by user):
  487.      */
  488.     strcpy (rg[i].rname, ".$");        /* num args at current macro*/
  489.     rg[i].rauto = 1;
  490.     rg[i].rval  = 0;
  491.     rg[i].rflag = RF_READ;
  492.     rg[i].rfmt  = '1';
  493.     i++;
  494.     
  495.     strcpy (rg[i].rname, ".A");        /* 1 for nroff */
  496.     rg[i].rauto = 1;
  497.     rg[i].rval  = 1;
  498.     rg[i].rflag = RF_READ;
  499.     rg[i].rfmt  = '1';
  500.     i++;
  501.     
  502.     strcpy (rg[i].rname, ".H");        /* hor resolution */
  503.     rg[i].rauto = 1;
  504.     rg[i].rval  = 1;
  505.     rg[i].rflag = RF_READ;
  506.     rg[i].rfmt  = '1';
  507.     i++;
  508.     
  509.     strcpy (rg[i].rname, ".T");        /* 1 for troff */
  510.     rg[i].rauto = 0;
  511.     rg[i].rval  = 0;
  512.     rg[i].rflag = RF_READ;
  513.     rg[i].rfmt  = '1';
  514.     i++;
  515.     
  516.     strcpy (rg[i].rname, ".V");        /* vert resolution */
  517.     rg[i].rauto = 1;
  518.     rg[i].rval  = 1;
  519.     rg[i].rflag = RF_READ;
  520.     rg[i].rfmt  = '1';
  521.     i++;
  522.     
  523.     strcpy (rg[i].rname, ".a");
  524.     rg[i].rauto = 1;
  525.     rg[i].rval  = 0;
  526.     rg[i].rflag = RF_READ;
  527.     rg[i].rfmt  = '1';
  528.     i++;
  529.     
  530.     strcpy (rg[i].rname, ".c");
  531.     rg[i].rauto = 1;
  532.     rg[i].rval  = 0;
  533.     rg[i].rflag = RF_READ;
  534.     rg[i].rfmt  = '1';
  535.     i++;
  536.     
  537.     strcpy (rg[i].rname, ".d");
  538.     rg[i].rauto = 1;
  539.     rg[i].rval  = 0;
  540.     rg[i].rflag = RF_READ;
  541.     rg[i].rfmt  = '1';
  542.     i++;
  543.     
  544.     strcpy (rg[i].rname, ".f");        /* current font (1-4) */
  545.     rg[i].rauto = 1;
  546.     rg[i].rval  = 1;
  547.     rg[i].rflag = RF_READ;
  548.     rg[i].rfmt  = '1';
  549.     i++;
  550.     
  551.     strcpy (rg[i].rname, ".h");
  552.     rg[i].rauto = 1;
  553.     rg[i].rval  = 0;
  554.     rg[i].rflag = RF_READ;
  555.     rg[i].rfmt  = '1';
  556.     i++;
  557.     
  558.     strcpy (rg[i].rname, ".i");        /* current indent */
  559.     rg[i].rauto = 1;
  560.     rg[i].rval  = 0;
  561.     rg[i].rflag = RF_READ;
  562.     rg[i].rfmt  = '1';
  563.     i++;
  564.     
  565.     strcpy (rg[i].rname, ".l");        /* current line length */
  566.     rg[i].rauto = 1;
  567.     rg[i].rval  = PAGEWIDTH - 1;
  568.     rg[i].rflag = RF_READ;
  569.     rg[i].rfmt  = '1';
  570.     i++;
  571.     
  572.     strcpy (rg[i].rname, ".n");
  573.     rg[i].rauto = 1;
  574.     rg[i].rval  = 0;
  575.     rg[i].rflag = RF_READ;
  576.     rg[i].rfmt  = '1';
  577.     i++;
  578.     
  579.     strcpy (rg[i].rname, ".o");        /* current offset */
  580.     rg[i].rauto = 1;
  581.     rg[i].rval  = 0;
  582.     rg[i].rflag = RF_READ;
  583.     rg[i].rfmt  = '1';
  584.     i++;
  585.     
  586.     strcpy (rg[i].rname, ".p");        /* current page len */
  587.     rg[i].rauto = 1;
  588.     rg[i].rval  = PAGELEN;
  589.     rg[i].rflag = RF_READ;
  590.     rg[i].rfmt  = '1';
  591.     i++;
  592.     
  593.     strcpy (rg[i].rname, ".s");        /* current point size */
  594.     rg[i].rauto = 1;
  595.     rg[i].rval  = 1;
  596.     rg[i].rflag = RF_READ;
  597.     rg[i].rfmt  = '1';
  598.     i++;
  599.     
  600.     strcpy (rg[i].rname, ".t");
  601.     rg[i].rauto = 1;
  602.     rg[i].rval  = 0;
  603.     rg[i].rflag = RF_READ;
  604.     rg[i].rfmt  = '1';
  605.     i++;
  606.     
  607.     strcpy (rg[i].rname, ".u");
  608.     rg[i].rauto = 1;
  609.     rg[i].rval  = 0;
  610.     rg[i].rflag = RF_READ;
  611.     rg[i].rfmt  = '1';
  612.     i++;
  613.     
  614.     strcpy (rg[i].rname, ".v");        /* current v line spacing */
  615.     rg[i].rauto = 1;
  616.     rg[i].rval  = 1;
  617.     rg[i].rflag = RF_READ;
  618.     rg[i].rfmt  = '1';
  619.     i++;
  620.     
  621.     strcpy (rg[i].rname, ".w");        /* width of prev char */
  622.     rg[i].rauto = 1;
  623.     rg[i].rval  = 1;
  624.     rg[i].rflag = RF_READ;
  625.     rg[i].rfmt  = '1';
  626.     i++;
  627.     
  628.     strcpy (rg[i].rname, ".x");
  629.     rg[i].rauto = 1;
  630.     rg[i].rval  = 0;
  631.     rg[i].rflag = RF_READ;
  632.     rg[i].rfmt  = '1';
  633.     i++;
  634.     
  635.     strcpy (rg[i].rname, ".y");
  636.     rg[i].rauto = 1;
  637.     rg[i].rval  = 0;
  638.     rg[i].rflag = RF_READ;
  639.     rg[i].rfmt  = '1';
  640.     i++;
  641.     
  642.     strcpy (rg[i].rname, ".z");
  643.     rg[i].rauto = 1;
  644.     rg[i].rval  = 0;
  645.     rg[i].rflag = RF_READ;
  646.     rg[i].rfmt  = '1';
  647.  
  648.     /*
  649.      *   page controls...
  650.      */
  651.     pg.curpag   = 0;
  652.     pg.newpag   = 1;
  653.     pg.lineno   = 0;
  654.     pg.plval    = PAGELEN;
  655.     pg.m1val    = 2;
  656.     pg.m2val    = 2;
  657.     pg.m3val    = 2;
  658.     pg.m4val    = 2;
  659.     pg.bottom   = pg.plval - pg.m4val - pg.m3val;
  660.     pg.offset   = 0;
  661.     pg.frstpg   = 0;
  662.     pg.lastpg   = 30000;
  663.     pg.ehead[0] = pg.ohead[0] = '\n';
  664.     pg.efoot[0] = pg.ofoot[0] = '\n';
  665.     for (i = 1; i < MAXLINE; ++i)
  666.     {
  667.         pg.ehead[i] = pg.ohead[i] = EOS;
  668.         pg.efoot[i] = pg.ofoot[i] = EOS;
  669.     }
  670.     pg.ehlim[LEFT]  = pg.ohlim[LEFT]  = dc.inval;
  671.     pg.eflim[LEFT]  = pg.oflim[LEFT]  = dc.inval;
  672.     pg.ehlim[RIGHT] = pg.ohlim[RIGHT] = dc.rmval;
  673.     pg.eflim[RIGHT] = pg.oflim[RIGHT] = dc.rmval;
  674.  
  675.     /*
  676.      *   output buffer controls...
  677.      */
  678.     co.outp   = 0;
  679.     co.outw   = 0;
  680.     co.outwds = 0;
  681.     co.lpr    = FALSE;
  682.     co.outesc = 0;
  683.     for (i = 0; i < MAXLINE; ++i)
  684.         co.outbuf[i] = EOS;
  685.  
  686.     /*
  687.      *   macros...
  688.      */
  689.     for (i = 0; i < MXMDEF; ++i)
  690.         mac.mnames[i] = NULL_CPTR;
  691.     for (i = 0; i < MACBUF; ++i)
  692.         mac.mb[i] = EOS;
  693.     for (i = 0; i < MAXPBB; ++i)
  694.         mac.pbb[i] = EOS;
  695.     mac.lastp = 0;
  696.     mac.emb   = &mac.mb[0];
  697.     mac.ppb   = NULL_CPTR;
  698.  
  699.     /*
  700.      *   file descriptors (for sourced files)
  701.      */
  702.     for (i = 0; i < Nfiles+1; ++i)
  703.         sofile[i] = NULL_FPTR;
  704. }
  705.  
  706.  
  707.  
  708.  
  709. /*------------------------------*/
  710. /*    pswitch            */
  711. /*------------------------------*/
  712. pswitch (p, q)
  713. register char  *p;
  714. register int   *q;
  715. {
  716.  
  717. /*
  718.  *    process switch values from command line
  719.  */
  720.  
  721.     int     swgood;
  722.     char    mfile[256];
  723.     char   *ptmac;
  724.     int    indx;
  725.     int    val;
  726.  
  727.     swgood = TRUE;
  728.     if (*p == '-')
  729.     {
  730.         /*
  731.          *   since is STILL use the goofy atari/dri xmain code, i
  732.          *   look for both upper and lower case. if you use dLibs
  733.          *   (and if its startup code does not ucase the cmd line),
  734.          *   you can probably look for just lower case. gulam and
  735.          *   other shells typically don't change case of cmd line.
  736.          */
  737.         switch (*++p)
  738.         {
  739.         case 0:                    /* stdin */
  740.             break;
  741.  
  742.         case 'a':                 /* font changes */
  743.         case 'A': 
  744.             dc.dofnt = NO;
  745.             break;
  746.  
  747.         case 'b':                 /* backspace */
  748.         case 'B': 
  749.             dc.bsflg = TRUE;
  750.             break;
  751.  
  752.         case 'd':                 /* debug mode */
  753.         case 'D': 
  754.             dbg_stream = fopen (dbgfile, "w");
  755.             debugging  = TRUE;
  756.             if (dbg_stream == NULL_FPTR)
  757.             {
  758.                 fprintf (err_stream,
  759.                     "***%s: unable to open debug file %s\n",
  760.                     myname, dbgfile);
  761.  
  762.                 dbg_stream  = stderr;
  763.             }
  764.             break;
  765.  
  766.         case 'h':                 /* hold screen */
  767.         case 'H': 
  768.             hold_screen = TRUE;
  769.             break;
  770.  
  771.         case 'l':                 /* to lpr (was P) */
  772.         case 'L': 
  773. #ifdef GEMDOS
  774.             out_stream = (FILE *) 0;
  775. #else
  776.             out_stream = fopen (printer, "w");
  777. #endif
  778.             co.lpr = TRUE;
  779.             break;
  780.  
  781.         case 'm':                 /* macro file */
  782.         case 'M': 
  783.             /*
  784.              *   build macro file name. start with lib
  785.              *
  786.              *   put c:\lib\tmac in environment so we can
  787.              *   read it here. else use default. if you want
  788.              *   file from cwd, "setenv TMACDIR ." from shell.
  789.              *
  790.              *   we want file names like "tmac.an" (for -man)
  791.              */
  792.             if (ptmac = getenv ("TMACDIR"))
  793.             {
  794.                 /*
  795.                  *   this is the lib path (e.g. "c:\lib\tmac")
  796.                  */
  797.                 strcpy (mfile, ptmac);
  798.  
  799.                 /*
  800.                  *   this is the prefix (i.e. "\tmac.")
  801.                  */
  802.                 strcat (mfile, TMACPRE);
  803.             }
  804.             else
  805.                 /*
  806.                  *   use default lib/prefix (i.e.
  807.                  *   "c:\lib\tmac\tmac.")
  808.                  */
  809.                 strcpy (mfile, TMACFULL);
  810.  
  811.             /*
  812.              *   finally, add extension (e.g. "an")
  813.              */
  814.             strcat (mfile, ++p);
  815.  
  816.             /*
  817.              *   open file and read it
  818.              */
  819.             if ((sofile[0] = fopen (mfile, "r")) == NULL_FPTR)
  820.             {
  821.                 fprintf (stderr,
  822.                     "***%s: unable to open macro file %s\n",
  823.                     myname, mfile);
  824.                 err_exit (-1);
  825.             }
  826.             profile ();
  827.             fclose (sofile[0]);
  828.             break;
  829.  
  830.         case 'o':                 /* output error log */
  831.         case 'O': 
  832.             if (!*(p+1))
  833.             {
  834.                 fprintf (stderr,
  835.                     "***%s: no error file specified\n",
  836.                     myname);
  837.                 err_exit (-1);
  838.             }
  839.             if ((err_stream = fopen (p+1, "w")) == NULL_FPTR)
  840.             {
  841.                 fprintf (stderr,
  842.                     "***%s: unable to open error file %s\n",
  843.                     myname, p+1);
  844.                 err_exit (-1);
  845.             }
  846.             break;
  847.  
  848.         case 'p':                 /* .po, .pn */
  849.         case 'P':
  850.             if (*(p+1) == 'o' || *(p+1) == 'O')    /* -po___ */
  851.             {
  852.                 p += 2;
  853.                 set (&pg.offset, ctod (p), '1', 0, 0, HUGE);
  854.                 set_ireg (".o", pg.offset, 0);
  855.             }
  856.             else if (*(p+1) == 'n' || *(p+1) == 'N')/* -pn___ */
  857.             {
  858.                 p += 2;
  859.                 set (&pg.curpag, ctod (p) - 1, '1', 0, -HUGE, HUGE);
  860.                 pg.newpag = pg.curpag + 1;
  861.                 set_ireg ("%", pg.newpag, 0);
  862.             }
  863.             else if (*(p+1) == 'l' || *(p+1) == 'L')/* -pl___ */
  864.             {
  865.                 p += 2;
  866.                 set (&pg.plval, ctod (p) - 1, '1', 0,
  867.                     pg.m1val + pg.m2val + pg.m3val + pg.m4val + 1,
  868.                     HUGE);
  869.                 set_ireg (".p", pg.plval, 0);
  870.                 pg.bottom = pg.plval - pg.m3val - pg.m4val;
  871.             }
  872.             else                    /* -p___ */
  873.             {
  874.                 p++;
  875.                 set (&pg.offset, ctod (p), '1', 0, 0, HUGE);
  876.                 set_ireg (".o", pg.offset, 0);
  877.             }
  878.             break;
  879.  
  880.         case 'r':                /* set number reg */
  881.         case 'R':
  882.             if (!isalpha (*(p+1)))
  883.             {
  884.                 fprintf (stderr,
  885.                     "***%s: invalid number register name (%c)\n",
  886.                     myname, (int) *(p+1));
  887.             }
  888.             else
  889.             {
  890.                 /*
  891.                  *   indx is the user num register and val
  892.                  *   is the final value.
  893.                  */
  894.                 indx = tolower (*(p+1)) - 'a';
  895.                 val  = atoi (p+2);
  896.                 set (&dc.nr[indx], val, '1', 0, -INFINITE, INFINITE);
  897.             }
  898.             break;
  899.  
  900.         case 's':                 /* page step mode */
  901.         case 'S': 
  902.             stepping = TRUE;
  903.             break;
  904.  
  905.         case 'v':                 /* version */
  906.         case 'V': 
  907.             printf ("%s\n", version);
  908.             *q = TRUE;
  909.             break;
  910.  
  911.         case '0':                 /* last page */
  912.         case '1': 
  913.         case '2': 
  914.         case '3': 
  915.         case '4': 
  916.         case '5': 
  917.         case '6': 
  918.         case '7': 
  919.         case '8': 
  920.         case '9': 
  921.             pg.lastpg = ctod (p);
  922.             break;
  923.  
  924.         default:                 /* illegal */
  925.             swgood = FALSE;
  926.             break;
  927.         }
  928.     }
  929.     else if (*p == '+')                /* first page */
  930.     {
  931.         pg.frstpg = ctod (++p);
  932.     }
  933.     else                        /* illegal */
  934.     {
  935.         swgood = FALSE;
  936.     }
  937.  
  938.  
  939.     if (swgood == FALSE)
  940.     {
  941.         fprintf (stderr, "***%s: illegal switch %s\n", myname, p);
  942.         return (ERR);
  943.     }
  944.  
  945.     return (OK);
  946. }
  947.  
  948.  
  949.  
  950.  
  951. /*------------------------------*/
  952. /*    profile            */
  953. /*------------------------------*/
  954. profile ()
  955. {
  956.  
  957. /*
  958.  *    process input files from command line
  959.  */
  960.  
  961.     char    ibuf[MAXLINE];
  962.  
  963.     /*
  964.      *   handle nesting of includes (.so). note that .so causes dc.flevel
  965.      *   to be increased...
  966.      */
  967.     for (dc.flevel = 0; dc.flevel >= 0; dc.flevel -= 1)
  968.     {
  969.         while (getlin (ibuf, sofile[dc.flevel]) != EOF)
  970.         {
  971.             /*
  972.              *   if line is a command or text
  973.              */
  974.             if (ibuf[0] == dc.cmdchr)
  975.             {
  976.                 comand (ibuf);
  977.             }
  978.             else
  979.             {
  980.                 /*
  981.                  *   this is a text line. first see if
  982.                  *   first char is space. if it is, break
  983.                  *   line.
  984.                  */
  985.                 if (ibuf[0] == ' ')
  986.                     robrk ();
  987.                 text (ibuf);
  988.             }
  989.         }
  990.  
  991.         /*
  992.          *   close included file
  993.          */
  994.         if (dc.flevel > 0)
  995.             fclose (sofile[dc.flevel]);
  996.     }
  997.     if (pg.lineno > 0)
  998.         space (HUGE);
  999. }
  1000.  
  1001.  
  1002.  
  1003.  
  1004.  
  1005.